#coding:utf-8

import Config;
import wx;
import os;
import wx.lib.rcsizer as rcs;
import wx.lib.intctrl;
import Global;
import Loading;
import string;
import ELog;
import traceback;
import array;
import time;
import numpy;  
import matplotlib;
import matplotlib.figure;
import matplotlib.backends.backend_wxagg;
import matplotlib.backends.backend_wx;
from mpl_toolkits.axes_grid1.axes_divider import make_axes_area_auto_adjustable
from matplotlib import rcParams
rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['Tahoma']
rcParams['font.size'] = '8'

try:
    from agw import fourwaysplitter as FWS
except ImportError: # if it's not there locally, try the wxPython lib.
    try:
        import wx.lib.agw.fourwaysplitter as FWS
    except ImportError:
        exit()

#菜单ID
from AppIds import *

import SerialUtil
import wx.lib.newevent

#Frame start
SERIAL_GENIUS_FS_CHAR=0x0F;
#Slash
SERIAL_GENIUS_SL_CHAR=0x1F;

#二维图像模块
class Video(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, style=wx.BORDER_DOUBLE);

        ############# 状态信息 ############
        #该模块是否启用
        self.isUsing=False;

        ############# 配置信息 ############
        self.video_width=160;
        self.video_height=90;
        self.video_data=[];
        self.video_data_gray=[];
        self.video_gray=True;

        self.video1_width=160;
        self.video1_height=90;
        self.video1_data=[];
        self.video1_data_gray=[];
        self.video1_gray=True;

        self.currentShow=0;
        self.recvVideoLength=0;
        self.saveJPG=False;
        
        self.dataBuffer=[];
        self.videoDataParseState=0;
        self.videoDataParseRow=0;
        self.videoDataParseCol=0;
        self.videoDataParseRGB=0;
        
        ############# 开始布局 ###########
        gridSizer = rcs.RowColSizer();
        rowTotal=3;
        colTotal=4;

        #标题
        title=wx.StaticText(self, -1, u"二维图像");
        title.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD ));
        gridSizer.Add(title, pos=(0,0), size=(1, colTotal), flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL);

        #绘图区
        self.figure=matplotlib.figure.Figure(figsize=(1,1));
        self.figure.subplots_adjust(left=0.00, bottom=0.00, right=1.00, top=1.00, wspace=None, hspace=None);
        self.axes=self.figure.add_subplot(111);
        self.canvas = matplotlib.backends.backend_wxagg.FigureCanvasWxAgg(self, 20, self.figure);
        gridSizer.Add(self.canvas, pos=(1,0), size=(1, colTotal), flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL);
        make_axes_area_auto_adjustable(self.axes);
        
        
        #测试绘图        
        self.axes.imshow([[[1.0, 1.0, 1.0] for col in range(160)] for row in range(90)]);
               
        #清空
        btn = wx.Button(self, -1, u"清空")
        self.Bind(wx.EVT_BUTTON, self.OnClearData, btn);
        gridSizer.Add(btn, pos=(2, 0), size=(1,1), flag=wx.ALIGN_CENTER_VERTICAL);
        
        #保存
        btn = wx.Button(self, -1, u"保存")
        self.Bind(wx.EVT_BUTTON, self.OnSaveData, btn);
        gridSizer.Add(btn, pos=(2, 1), size=(1,1), flag=wx.ALIGN_CENTER_VERTICAL);
        
        #显示接收到图像帧数
        self.labelVideoLength= wx.StaticText(self, -1, u"接收帧数：0");
        gridSizer.Add(self.labelVideoLength, pos=(2, 2), size=(1,1), flag=wx.ALIGN_CENTER_VERTICAL);

        #保存到JPG文件
        ck=wx.CheckBox(self, -1, u"同时保存到JPG");
        ck.Bind(wx.EVT_CHECKBOX, self.OnSaveJpg);
        gridSizer.Add(ck, pos=(2, 3), size=(1,1), flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL);
        if Config.APP_CONFIG['module_video']['saveJpg']=='1':
            ck.SetValue(True);
            self.saveJPG=True;

        
        #设置变宽信息
        gridSizer.AddGrowableCol(2);
        gridSizer.AddGrowableRow(1);


        ############# 结束布局 ###########
        self.SetSizer(gridSizer);
        self.SetAutoLayout(True);
        
        #更新GUI数据的线程
        (self.UpdateDataEvent, self.UPDATA_DATA_EVENT) = wx.lib.newevent.NewEvent();
        self.Bind(self.UPDATA_DATA_EVENT, self.RefreshVideo)

    #是否保存到JPG
    def OnSaveJpg(self, event):
        if event.GetEventObject().GetValue():
            self.saveJPG=True;
            Config.APP_CONFIG['module_video']['saveJpg']='1';
        else:
            self.saveJPG=False;
            Config.APP_CONFIG['module_video']['saveJpg']='0';
            
    #是否保存到JPG
    def OnSaveData(self, event):
        self.canvas.print_jpg(time.strftime('Video_static_%Y%m%d_%H_%M_%S.jpg',time.localtime(time.time())));
        wx.MessageBox(u'保存成功');

    #新增串口数据，被串口接收所调用
    def RecvData(self, data):
        self.dataBuffer.extend(data);
        while (self.videoDataParseState==0 and len(self.dataBuffer)>=9) or \
              (self.videoDataParseState==1 and len(self.dataBuffer)>0):
            try:   
                if self.videoDataParseState==0:
                    
                    #找到帧头
                    while len(self.dataBuffer)>1:
                        if self.dataBuffer[0]==SERIAL_GENIUS_FS_CHAR:
                            break;
                        if self.dataBuffer[0]==SERIAL_GENIUS_SL_CHAR:
                            self.dataBuffer.pop(0);
                        self.dataBuffer.pop(0);
                    
                    if len(self.dataBuffer)<9:
                        break;
                    
                    # 0F 命令 长度 校验 宽度H 宽度L 高度H 高度L 颜色模式...
                    
                    #找到帧头
                    if self.dataBuffer[0]==SERIAL_GENIUS_FS_CHAR:
                        if self.dataBuffer[1]==0x0D:
                            if self.dataBuffer[3]==self.dataBuffer[1]^self.dataBuffer[2]:
                                self.videoDataParseState=1;
                                
                                valueH=self.dataBuffer[4];
                                valueL=self.dataBuffer[5];
                                width=(valueH<<8)|valueL;
                                
                                valueH=self.dataBuffer[6];
                                valueL=self.dataBuffer[7];
                                height=(valueH<<8)|valueL;

                                mode=self.dataBuffer[8];
                                
                                if 0<width<=1000 and 0<height<=1000 and 1<=mode<=2:
                                    #print width, height, mode;
                                    if self.currentShow==0:
                                        
                                        self.video1_width=width;
                                        self.video1_height=height;                                        
                                        if mode==2:
                                            self.video1_gray=True;
                                        else:
                                            self.video1_gray=False;
                                        
                                    elif self.currentShow==1:
                                        
                                        self.video_width=width;
                                        self.video_height=height;                                        
                                        if mode==2:
                                            self.video_gray=True;
                                        else:
                                            self.video_gray=False;
                                        
                                    #根据发送过来的图像头信息初始化数组
                                    self.InitVideoData();

                                    #初始化接收行列
                                    self.videoDataParseRow=0;
                                    self.videoDataParseCol=0;
                                    self.videoDataParseRGB=0;

                                    #弹出已经初始化的数据
                                    for i in range(0,9):
                                        self.dataBuffer.pop(0);

                                    self.videoDataParseState=1;
                                    
                                else:
                                    #错误的帧数据
                                    for i in range(0,9):
                                        self.dataBuffer.pop(0);
                            else:
                                #数据校验出错
                                self.dataBuffer.pop(0);
                                self.dataBuffer.pop(0);
                                self.dataBuffer.pop(0);
                                self.dataBuffer.pop(0);
                        else:
                            #不是我们的数据
                            self.dataBuffer.pop(0);
                            self.dataBuffer.pop(0);
                            self.dataBuffer.pop(0);
                            self.dataBuffer.pop(0);
                    else:
                        #不是一个帧头，在这里忽略
                        self.dataBuffer.pop(0);
                            
                elif self.videoDataParseState==1:

                    if self.dataBuffer[0]==SERIAL_GENIUS_SL_CHAR and len(self.dataBuffer)<2:
                        break;

                    #解析数据
                    data=self.GetNextDataByte();
                    if self.currentShow==0:
                        
                        if self.video1_gray:

                            self.video1_data[self.videoDataParseRow][self.videoDataParseCol]=[data/255.0, data/255.0, data/255.0];
                            
                            self.videoDataParseCol+=1;
                            
                            if self.videoDataParseCol==self.video1_width:
                                self.videoDataParseRow+=1;
                                self.videoDataParseCol=0;

                                if self.videoDataParseRow==self.video1_height:
                                    #发送更新图像事件
                                    wx.PostEvent(self,self.UpdateDataEvent(frame=0));
                                    self.currentShow=1;
                                    self.videoDataParseState=0;
                                
                        else:

                            self.video1_data[self.videoDataParseRow][self.videoDataParseCol][self.videoDataParseRGB]=data/255.0;

                            self.videoDataParseRGB+=1;

                            if self.videoDataParseRGB==3:
                                self.videoDataParseCol+=1;
                                self.videoDataParseRGB=0;
                                
                                if self.videoDataParseCol==self.video1_width:
                                    self.videoDataParseRow+=1;
                                    self.videoDataParseCol=0;

                                    if self.videoDataParseRow==self.video1_height:
                                        #发送更新图像事件
                                        wx.PostEvent(self,self.UpdateDataEvent(frame=0));
                                        self.currentShow=1;
                                        self.videoDataParseState=0;
                                        
                            
                    elif self.currentShow==1:
                        
                        if self.video_gray:

                            self.video_data[self.videoDataParseRow][self.videoDataParseCol]=[data/255.0, data/255.0, data/255.0];
                            
                            self.videoDataParseCol+=1;
                            
                            if self.videoDataParseCol==self.video_width:
                                self.videoDataParseRow+=1;
                                self.videoDataParseCol=0;

                                if self.videoDataParseRow==self.video_height:
                                    #发送更新图像事件
                                    wx.PostEvent(self,self.UpdateDataEvent(frame=1));
                                    self.currentShow=0;
                                    self.videoDataParseState=0;
                                    
                                
                        else:

                            self.video_data[self.videoDataParseRow][self.videoDataParseCol][self.videoDataParseRGB]=data/255.0;

                            self.videoDataParseRGB+=1;

                            if self.videoDataParseRGB==3:
                                self.videoDataParseCol+=1;
                                self.videoDataParseRGB=0;
                                
                                if self.videoDataParseCol==self.video_width:
                                    self.videoDataParseRow+=1;
                                    self.videoDataParseCol=0;

                                    if self.videoDataParseRow==self.video_height:
                                        #发送更新图像事件
                                        wx.PostEvent(self,self.UpdateDataEvent(frame=1));
                                        self.currentShow=0;
                                        self.videoDataParseState=0;
                                        

                        
            except:
                self.videoDataParseState=0;
                break;
            
      
    #获取数据部分中下一个数据（如果转义自动去除转义符号）
    def GetNextDataByte(self):
        if self.dataBuffer[0]==SERIAL_GENIUS_SL_CHAR:
            self.dataBuffer.pop(0);
        return self.dataBuffer.pop(0); 

    #刷新视频数据，从变量中显示到图形中
    def RefreshVideo(self, event):
        
        if event.frame==0:
            self.axes.imshow(self.video1_data, interpolation='nearest');
            
        elif event.frame==1:
            self.axes.imshow(self.video_data, interpolation='nearest');
        
        self.axes.grid(True);

        self.recvVideoLength+=1;    
        self.labelVideoLength.SetLabel(u'图像帧数: '+str(self.recvVideoLength));
        self.canvas.draw();
        #Save JPG
        if self.saveJPG:
            self.canvas.print_jpg('Video_'+str(self.recvVideoLength)+time.strftime('_%Y%m%d_%H_%M_%S.jpg',time.localtime(time.time())));
        
    #初始化二维图像数据
    def InitVideoData(self):
        if self.currentShow==0:
            self.video1_data=[[[1.0, 1.0, 1.0] for col in range(self.video1_width)] for row in range(self.video1_height)];
        elif self.currentShow==1:
            self.video_data=[[[1.0, 1.0, 1.0] for col in range(self.video_width)] for row in range(self.video_height)];
        
    #清空数据
    def OnClearData(self, event):
        self.recvVideoLength=0;
        self.labelVideoLength.SetLabel(u'图像帧数: '+str(self.recvVideoLength));
        self.axes.imshow([[[1.0, 1.0, 1.0] for col in range(160)] for row in range(90)]);
        self.canvas.draw();
        self.axes.grid(True);
    
    #重绘函数
    def OnPaint(self, event):
        self.canvas.draw();
